package com.itdct.onflow.system.task.base

import com.itdct.onflow.core.extend.logDebug
import com.itdct.onflow.core.extend.logError
import com.itdct.onflow.core.util.TimeUtil
import com.itdct.onflow.system.task.constant.SysTaskCycleTypeConst
import com.itdct.onflow.system.task.constant.SysTaskExecuteStateConst
import com.itdct.onflow.system.task.constant.SysTaskRedisKey
import com.itdct.onflow.system.task.entity.SysTaskEntity
import org.springframework.data.redis.core.RedisTemplate

/**
 * @author Zhouwx
 * @date 2025/9/19 17:28:17
 * @version 1.0
 * @description
 */
abstract class BaseTask {
    fun run(sysTaskEntity: SysTaskEntity, redisTemplate: RedisTemplate<String, Any>) {
        val id = sysTaskEntity.id ?: throw RuntimeException("定时任务ID为空")
        val result = redisTemplate.opsForValue().increment(SysTaskRedisKey.SYS_TASK_LOCK + id)
        if (result == 1L) {
            try {
                redisTemplate.expire(SysTaskRedisKey.SYS_TASK_LOCK + id, 60, java.util.concurrent.TimeUnit.MINUTES)
                runTask(sysTaskEntity)
            } catch (e: Exception) {
                logError("定时任务执行失败", e)
            } finally {
                redisTemplate.delete(SysTaskRedisKey.SYS_TASK_LOCK + id)
            }
        } else {
            logDebug("该任务已被其他节点执行")
        }
    }

    private fun runTask(sysTaskEntity: SysTaskEntity) {
        execute(sysTaskEntity)
        val cycleType = sysTaskEntity.cycleType
        when (cycleType) {
            SysTaskCycleTypeConst.CYCLE,
            SysTaskCycleTypeConst.CRON ->
                sysTaskEntity.executeState = SysTaskExecuteStateConst.WAITING

            SysTaskCycleTypeConst.SPECIFIC -> {
                val specifyTime = sysTaskEntity.specifyTime
                specifyTime?.also {
                    val timeStrings = specifyTime.split(",")
                    val nowTime = System.currentTimeMillis()
                    var isFinish = true
                    for (timeString in timeStrings) {
                        val executeTime: Long = TimeUtil.timeStringToDate(timeString, TimeUtil.yyyyMMddHHmmss_HYPHEN)!!.getTime()
                        if (nowTime < executeTime) {
                            isFinish = false
                            break
                        }
                    }
                    if (isFinish) {
                        sysTaskEntity.executeState = SysTaskExecuteStateConst.FINISH
                    } else {
                        sysTaskEntity.executeState = SysTaskExecuteStateConst.WAITING
                    }
                }
            }
        }
    }

    abstract fun execute(sysTaskEntity: SysTaskEntity)


}